package com.ddwl.order.service;

import com.alibaba.fastjson.JSON;
import com.ddwl.common.constant.*;
import com.ddwl.common.exception.ParamException;
import com.ddwl.common.feign.api.*;
import com.ddwl.common.util.BeanConverUtils;
import com.ddwl.common.util.MySqlUtil;
import com.ddwl.common.util.UUIDGenerator;
import com.ddwl.order.dao.*;
import com.ddwl.order.dao.model.*;
import com.ddwl.schema.bo.base.PageBo;
import com.ddwl.schema.bo.funds.OrderRefundCreBo;
import com.ddwl.schema.bo.gate.DingTalkBo;
import com.ddwl.schema.bo.goods.SupplierBo;
import com.ddwl.schema.bo.message.TempSentSmsBo;
import com.ddwl.schema.bo.order.*;
import com.ddwl.schema.util.DateUtil;
import com.ddwl.schema.vo.base.PageVo;
import com.ddwl.schema.vo.base.RestVo;
import com.ddwl.schema.vo.funds.OrderRefundsVo;
import com.ddwl.schema.vo.goods.SkuVo;
import com.ddwl.schema.vo.goods.SupplierVo;
import com.ddwl.schema.vo.order.*;
import com.ddwl.schema.vo.shop.ShopVo;
import com.ddwl.schema.vo.user.UserVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.util.StringUtil;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 售后订单处理
 * @author wenbin
 */
@Service
@RefreshScope
@Slf4j
public class ShopAfterSaleOrderServer {


    @Resource
    private OrderInfoDao orderInfoDao;
    @Resource
    private ShopAfterSaleOrderDao shopAfterSaleOrderDao;
    @Resource
    private OrderAddressServer orderAddressServer;
    @Resource
    private OrderPayServer orderPayServer;
    @Resource
    private OrderSpuDao orderSpuDao;
    @Resource
    private OrderAddrDao orderAddrDao;
    @Resource
    private OrderPayDao orderPayDao;
    @Resource
    private FundsApi fundsApi;
    @Resource
    private WalletApi walletApi;
    @Resource
    private GoodsApi goodsApi;
    @Resource
    private ShopApi shopApi;
    @Resource
    private UserApi userApi;
    @Resource
    private MessageApi messageApi;

    //售后单过期时间
    @Value("${ddwl.order.after_sale_expired_time}")
    private Integer afterSaleExpiredTime;
    //售后单过期时间
    @Value("${ddwl.order.after_sale_auto_refund_time}")
    private Integer afterSaleAutoRefundTime;
    @Resource
    private RabbitTemplate rabbitTemplate;


    @GlobalTransactional(rollbackFor = Throwable.class)
    public String create(CreateAfterSaleOrderBo bo,String userId,String userName){
        //售后校验
        OrderSpu spu = checkValue(bo);
        //店铺id
        OrderInfo orderInfo = orderInfoDao.selectByPrimaryKey(spu.getOrderId());
        ShopVo shopVo = shopApi.getShopById(orderInfo.getShopId()).getResult();
        UserVo userVo = userApi.getProfile(userId).getResult();
        bo.setShopId(orderInfo.getShopId());
        bo.setShopName(shopVo.getName());
        bo.setShopLogo(shopVo.getLogo());
        bo.setFare(orderInfo.getFare());
        //createEntity
        AfterSaleOrder orderInfo1 = createEntity(bo,userId,userName,spu,userVo);
        //更新原零售单售后状态
        updateOrderInfoAfterStatus(spu);
        //如果发生退款更新佣金
        if(OrderEnum.AfterType.REFUND.getCode().equals(orderInfo1.getAfterSaleType())||
                OrderEnum.AfterType.RETURN.getCode().equals(orderInfo1.getAfterSaleType())) {
            walletApi.createOrderRefundAmount(orderInfo1.getOrderId(), orderInfo1.getSpuOrderId(), orderInfo1.getAfterSaleAmount(), orderInfo1.getId(),orderInfo1.getSkuQty());
        }
        //发送短信
        ((ShopAfterSaleOrderServer) AopContext.currentProxy()).sentSms(shopVo.getUserTel());
        if (shopVo.getDefaultTag()==1){
            //发送钉钉消息
            DingTalkBo bo1=new DingTalkBo();
            bo1.setMessage("");
            bo1.setChannel(StatisticsEnum.channel.PENDING_AFTERSALE_COUNT.getId());
            rabbitTemplate.convertAndSend(RabbitMqConstants.DINGDING_TALK_MESSAGE,JSON.toJSONString(bo1));
        }
        return orderInfo1.getId();
    }


    @Async
    public void sentSms(String telPhone){
        TempSentSmsBo tempSentSmsBo = new TempSentSmsBo();
        tempSentSmsBo.setToPhone(telPhone);
        tempSentSmsBo.setTemplateCode(SmsTempCodeEnum.SHOP_AFTER_SALE.getCode());
        messageApi.sentSms(tempSentSmsBo);
    }

    /**
     * 构建entity
     */
    private AfterSaleOrder createEntity(CreateAfterSaleOrderBo bo, String userId, String userName, OrderSpu spu, UserVo userVo){
        AfterSaleOrder entity = BeanConverUtils.convertBean(bo, AfterSaleOrder.class);
        if (bo.getAfterSaleType().equals(OrderEnum.AfterType.RETURN.getCode())){
            OrderAddrVo orderAddr = orderAddressServer.getOrderAddr(spu.getOrderId());
            entity.setReSendAddr(orderAddr.getAddress());
            entity.setReSendRegion(orderAddr.getRegionId());
            entity.setReSendReceiver(orderAddr.getReceiver());
            entity.setReSendTel(orderAddr.getMobile());
        }
        if (bo.getAfterSaleType().equals(OrderEnum.AfterType.REFUND.getCode())){
            entity.setAutoRefundTime(DateUtil.addDay(Instant.now(),afterSaleAutoRefundTime));
        }
        entity.setSpuOrderId(spu.getId());
        entity.setOrderId(spu.getOrderId());
        entity.setSkuId(spu.getId());
        entity.setShopId(bo.getShopId());
        entity.setShopName(bo.getShopName());
        entity.setShopLogo(bo.getShopLogo());
        entity.setBarcode(bo.getBarcode());
        entity.setUserId(userId);
        entity.setUserName(userName);
        entity.setUserTel(userVo.getMobile());
        entity.setPlatformTag(1);
        entity.setAfterSaleStatus(OrderEnum.AfterStatus.APPLY.getCode());
        entity.setId(UUIDGenerator.getTimeUUID());
        if(bo.getAfterSaleType().equals(OrderEnum.AfterType.EXCHANGE.getCode())){
            SkuVo skuVo = goodsApi.detailNew(bo.getBarcode()).getResult();
            if (skuVo!=null){
                spu.setSkuCode(bo.getBarcode());
                spu.setItemId(skuVo.getItemId());
                spu.setSkuPic(skuVo.getImageUrl());
                spu.setSkuDesc(skuVo.getItemSpecs());
                spu.setSkuId(skuVo.getId());
                entity.setSkuId(skuVo.getId());
            }
        }
        entity.setSkuSnapshoot(JSON.toJSONString(spu));
        shopAfterSaleOrderDao.insert(entity);
        return entity;
    }

    /**
     * 退货校验
     */
    private OrderSpu checkValue(CreateAfterSaleOrderBo bo){
        OrderSpu spu = orderSpuDao.selectByPrimaryKey(bo.getSpuOrderId());
        if (!bo.getAfterSaleType().equals(OrderEnum.AfterType.EXCHANGE.getCode())){
            ParamException.isNull(bo.getAfterSaleAmount(),"售后退款金额为空");
            ParamException.isNull(bo.getSkuQty(),"售后数量为空");

        }
        ParamException.isTrue(spu==null,"订单["+bo.getSpuOrderId()+"]不存在");

        //判断退款金额不能超过总付款金额
        ParamException.isTrue(bo.getAfterSaleAmount().compareTo(spu.getRealPrice().multiply(new BigDecimal(spu.getSkuQty())))>0,"退款金额不能大于实际付款金额");

        AfterSaleOrder afterSaleOrder=new AfterSaleOrder();
        afterSaleOrder.setSpuOrderId(spu.getId());
        List<AfterSaleOrder> afterSaleOrderList = shopAfterSaleOrderDao.select(afterSaleOrder);
        if (afterSaleOrderList!=null&&afterSaleOrderList.size()!=0){
            ParamException.isTrue((afterSaleOrderList.stream()
                    .filter(o->o.getAfterSaleStatus()==6&&o.getSkuQty()!=null)
                    .mapToInt(AfterSaleOrder::getSkuQty).sum())
                    +(bo.getSkuQty()==null?0:bo.getSkuQty())>spu.getSkuQty(),"退货数量不能大于实际购买数量");
            for (AfterSaleOrder o:afterSaleOrderList) {
                ParamException.isTrue(o.getAfterSaleStatus()>=1&&o.getAfterSaleStatus()<=5,"有一个申请在处理中,请联系客服");
            }
        }
        //判断是否已经过售后保质期
        OrderInfo orderInfo=new OrderInfo();
        orderInfo.setId(spu.getOrderId());
        OrderInfo orderInfo2 = orderInfoDao.selectOne(orderInfo);
        ParamException.isTrue(orderInfo2!=null&&orderInfo2.getRepairTime()!=null&&orderInfo2.getRepairTime().compareTo(Instant.now())<0,"已过保修期,不能退换货,如有问题,联系客服");
        ParamException.isTrue(orderInfo2!=null&&orderInfo2.getStatus()==0,"订单未支付,不能退款");
        return spu;
    }

    /**
     * 更新订单售后状态
     *
     * */
    public void updateOrderInfoAfterStatus(OrderSpu spuBo) {
        OrderSpu spu=new OrderSpu();
        spu.setId(spuBo.getId());
        spu.setAfterSaleCount(spuBo.getAfterSaleCount()==null?0:spuBo.getAfterSaleCount()+1);
        spu.setAfterSaleStatus(1);
        orderSpuDao.updateByPrimaryKeySelective(spu);
        upSkuSnapshoot(spuBo.getOrderId());

    }

    /**
     * 更新快照售后状态
     */
    private void upSkuSnapshoot(String orderId){
        if (StringUtil.isEmpty(orderId)){
            return;
        }
        OrderSpu sp=new OrderSpu();
        sp.setOrderId(orderId);
        List<OrderSpu> orderSpus = orderSpuDao.select(sp);
        if (!CollectionUtils.isEmpty(orderSpus)){
            OrderInfo orderInfo = new OrderInfo();
            orderInfo.setId(orderId);
            orderInfo.setSkuSnapshoot(JSON.toJSONString(orderSpus));
            orderInfoDao.updateByPrimaryKeySelective(orderInfo);
        }
    }

    /**
     * 用户取消订单
     * @param bo
     * @param userId
     * @return
     */
    @GlobalTransactional(rollbackFor = Throwable.class)
    public void cancelAfterSaleOrder(ConfirmAfterSaleBo bo,String userId){
        String afterId=bo.getAfterId();
        if (StringUtils.hasText(bo.getSpuOrderId())){
            bo.setUserId(userId);
            List<Integer>list=new ArrayList<>();
            list.add(OrderEnum.AfterStatus.ACCEPT.getCode());
            list.add(OrderEnum.AfterStatus.APPLY.getCode());
            AfterSaleOrder afterSaleOrder1 = shopAfterSaleOrderDao.queryAfterSaleOrder(bo,list);
            ParamException.isNull(afterSaleOrder1,"当前状态不支持取消,请联系客服");
            afterId=afterSaleOrder1.getId();
        }
        AfterSaleOrder afterSaleOrder = shopAfterSaleOrderDao.selectByPrimaryKey(afterId);
        //OrderInfo orderInfo = orderInfoDao.selectByPrimaryKey(afterSaleOrder.getOrderId());
        //ParamException.isTrue(orderInfo==null,"原订单不存在");
        //ParamException.isTrue(afterSaleOrder.getAfterSaleStatus()>=3,"当前状态"+OrderEnum.AfterStatus.getValueByCode(afterSaleOrder.getAfterSaleStatus())+"不支持取消,请联系客服");
        shopAfterSaleOrderDao.closed(afterId,userId);
        OrderSpu orderSpu = new OrderSpu();
        orderSpu.setId(afterSaleOrder.getSpuOrderId());
        orderSpu.setIsAfterSale(0);
        orderSpu.setAfterSaleStatus(OrderEnum.AfterStatus.CANCEL.getCode());
        orderSpuDao.updateByPrimaryKeySelective(orderSpu);
        upSkuSnapshoot(afterSaleOrder.getOrderId());
        if(OrderEnum.AfterType.REFUND.getCode().equals(afterSaleOrder.getAfterSaleType())||
                OrderEnum.AfterType.RETURN.getCode().equals(afterSaleOrder.getAfterSaleType())) {
            walletApi.cancleOrderRefund(afterSaleOrder.getId());
        }
    }


    /**
     * 更新售后商品的售后状态
     * @param afterSaleOrder
     */
    private void updateOrderSpuAfterSaleStatus(AfterSaleOrder afterSaleOrder) {
        OrderSpu orderSpu = new OrderSpu();
        orderSpu.setId(afterSaleOrder.getSpuOrderId());
        List<AfterSaleOrder> afterSaleOrders = shopAfterSaleOrderDao.queryOrderSpuAfterSale(afterSaleOrder.getSpuOrderId());
        if(CollectionUtils.isEmpty(afterSaleOrders)){
            orderSpu.setIsAfterSale(0);
        }else {
            orderSpu.setIsAfterSale(2);
        }
        orderSpuDao.updateByPrimaryKeySelective(orderSpu);

        OrderSpu spu = orderSpuDao.selectByPrimaryKey(afterSaleOrder.getSpuOrderId());
        upSkuSnapshoot(spu.getOrderId());
    }


    /**
     * 拒绝用户售后单据
     * @param bo
     * @return
     */
    @GlobalTransactional(rollbackFor = Throwable.class)
    public void rejectAfterSaleOrder(ConfirmAfterSaleBo bo){
        ParamException.isBlank(bo.getAfterId(),"售后单号为空");
        ParamException.isBlank(bo.getRejectReason(),"拒绝原因为空");
        AfterSaleOrder afterSaleOrder = shopAfterSaleOrderDao.selectByPrimaryKey(bo.getAfterId());
        ParamException.isNull(afterSaleOrder,"售后单不存在");
        shopAfterSaleOrderDao.reject(bo.getAfterId(),bo.getRejectReason());
        OrderSpu orderSpu = new OrderSpu();
        orderSpu.setId(afterSaleOrder.getSpuOrderId());
        orderSpu.setIsAfterSale(0);
        orderSpu.setAfterSaleStatus(OrderEnum.AfterStatus.REJECT.getCode());
        orderSpuDao.updateByPrimaryKeySelective(orderSpu);
        upSkuSnapshoot(afterSaleOrder.getOrderId());
        if (!afterSaleOrder.getAfterSaleType().equals(OrderEnum.AfterType.EXCHANGE.getCode())){
            walletApi.cancleOrderRefund(afterSaleOrder.getId());
        }
    }


    /**
     * 分页查询订单包含商品信息
     * @param boPageBo
     * @return
     */
    public PageVo<AfterSaleOrderVo> getPage(PageBo<QueryAfterSaleOrderListBo> boPageBo){
        PageHelper.startPage(boPageBo.getPage(),boPageBo.getPageSize(), MySqlUtil.orderBy(boPageBo.getSort(),boPageBo.isAsc()));
        PageInfo<AfterSaleOrder> info = new PageInfo(shopAfterSaleOrderDao.queryAfterSaleOrderList(boPageBo.getParam()));
        List<AfterSaleOrderVo> list = BeanConverUtils.convertBeanList(info.getList(),AfterSaleOrderVo.class);
        fillDate(list);
        return new PageVo<>(info.getTotal(),boPageBo.getPage(),boPageBo.getPageSize(),list);
    }

    private void fillDate(List<AfterSaleOrderVo> list) {
        List<String> barcodes = list.stream().map(AfterSaleOrderVo::getBarcode).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(barcodes)){
            return;
        }
        List<SkuVo> skuVos = goodsApi.querySkuByBacodes(barcodes).getResult();
        if (!CollectionUtils.isEmpty(skuVos)){
            for (AfterSaleOrderVo vo:list) {
                for (SkuVo skuVo:skuVos) {
                    if (StringUtil.isNotEmpty(vo.getBarcode())&&skuVo.getBarcode().equals(vo.getBarcode())){
                        vo.setSkuVo(skuVo);
                    }
                }
            }
        }

    }


    /**
     * 分页查询订单包含商品信息api
     * @param boPageBo
     * @return
     */
    public PageVo<AfterSaleOrderVo> getApiPage(PageBo<QueryAfterSaleOrderListApiBo> boPageBo){
        PageHelper.startPage(boPageBo.getPage(),boPageBo.getPageSize(), MySqlUtil.orderBy(boPageBo.getSort(),boPageBo.isAsc()));

        QueryAfterSaleOrderListApiBo bo=boPageBo.getParam();
        ParamException.isTrue(bo.getAppId()==null,"appID为空");
        ParamException.isTrue(bo.getTimestamp()==null,"请求时间为空");
        SupplierBo supplierBo=new SupplierBo();
        supplierBo.setAppId(bo.getAppId());
        RestVo<PageVo<SupplierVo>> pageVoRestVo = goodsApi.querySupplierCategory(supplierBo);
        List<SupplierVo> data = pageVoRestVo.getResult().getData();
        ParamException.isTrue(data==null||data.size()==0,"appID不存在");
        List<String>supplierList= data.stream().map(supplierVo -> {return supplierVo.getId(); }).collect(Collectors.toList());
        bo.setSupplierList(supplierList);
        PageInfo<AfterSaleOrder> info = new PageInfo(shopAfterSaleOrderDao.queryAfterSaleOrderApiList(boPageBo.getParam()));
        List<AfterSaleOrderVo> list = BeanConverUtils.convertBeanList(info.getList(),AfterSaleOrderVo.class);
        return new PageVo<>(info.getTotal(),boPageBo.getPage(),boPageBo.getPageSize(),list);
    }


    /**
     * 用户更新售后物流信息
     * @param bo
     * @return
     */
    public void updateAfterSale(UpdateAfterSaleOrderBo bo, String userId){
        String afterId=bo.getAfterId();
        ParamException.isBlank(afterId,"售后单号为空");
        if (StringUtils.hasText(bo.getSpuOrderId())){
            ConfirmAfterSaleBo confirmAfterSaleBo=new ConfirmAfterSaleBo();
            confirmAfterSaleBo.setUserId(userId);
            confirmAfterSaleBo.setSpuOrderId(bo.getSpuOrderId());
            List<Integer>list=new ArrayList<>();
            list.add(OrderEnum.AfterStatus.ACCEPT.getCode());
            list.add(OrderEnum.AfterStatus.APPLY.getCode());
            AfterSaleOrder afterSaleOrder1 = shopAfterSaleOrderDao.queryAfterSaleOrder(confirmAfterSaleBo,list);
            ParamException.isNull(afterSaleOrder1,"当前状态不支持更新,请联系客服");
            afterId=afterSaleOrder1.getId();
        }
        AfterSaleOrder afterSaleOrder = shopAfterSaleOrderDao.selectByPrimaryKey(afterId);
        ParamException.isNull(afterSaleOrder);
        if(StringUtils.hasText(userId)){
            ParamException.isFalse(userId.equals(afterSaleOrder.getUserId()));
        }
        ParamException.isTrue(!afterSaleOrder.getAfterSaleStatus().equals(OrderEnum.AfterStatus.ACCEPT.getCode()),
                "当前状态"+OrderEnum.AfterStatus.getValueByCode(afterSaleOrder.getAfterSaleStatus())+"不可以填写物流信息,请联系客服");
        bo.setAfterId(afterId);
        shopAfterSaleOrderDao.updateAfter(bo);

    }

    /**
     * 后台填写寄回给客户物流信息
     * @param bo
     * @return
     */
    public void reLogistics(ConfirmAfterSaleBo bo){
        ParamException.isBlank(bo.getAfterId(),"售后单号为空");
        AfterSaleOrder afterSaleOrder = shopAfterSaleOrderDao.selectByPrimaryKey(bo.getAfterId());
        ParamException.isNull(afterSaleOrder);
        afterSaleOrder.setReLogisticsCode(bo.getReLogisticsCode());
        afterSaleOrder.setReLogisticsName(bo.getReLogisticsName());
        afterSaleOrder.setReLogisticsNo(bo.getReLogisticsNo());
        afterSaleOrder.setAfterSaleStatus(OrderEnum.AfterStatus.EXCHANGED.getCode());
        shopAfterSaleOrderDao.updateByPrimaryKeySelective(afterSaleOrder);
        //更新spu状态
        OrderSpu spu=new OrderSpu();
        spu.setId(afterSaleOrder.getSpuOrderId());
        spu.setAfterSaleStatus(OrderEnum.AfterStatus.EXCHANGED.getCode());
        orderSpuDao.updateByPrimaryKeySelective(spu);
    }

    /**
     * 后台审批订单
     * @param bo
     * @return
     */
    public void confirmAfterSale(ConfirmAfterSaleBo bo){

        ParamException.isBlank(bo.getAfterId(),"售后单号为空");
        //拒绝售后申请
        if (StringUtil.isNotEmpty(bo.getRejectReason())){
            rejectAfterSaleOrder(bo);
            return;
        }

        ParamException.isNull(bo.getAfterSaleType(),"售后类型为空");
        AfterSaleOrder afterSaleOrder = shopAfterSaleOrderDao.selectByPrimaryKey(bo.getAfterId());
        ParamException.isNull(afterSaleOrder);
        //退货换货
        if (afterSaleOrder.getAfterSaleType().equals(OrderEnum.AfterType.RETURN.getCode())
                ||afterSaleOrder.getAfterSaleType().equals(OrderEnum.AfterType.EXCHANGE.getCode())){
            ParamException.isBlank(bo.getAfterSaleTel(),"售后收件人电话为空");
            ParamException.isBlank(bo.getAfterSaleAddr(),"售后收件人地址为空");
            ParamException.isBlank(bo.getAfterSaleReceiver(),"售后收件人为空");
        }
        shopAfterSaleOrderDao.confirmAfter(bo,afterSaleOrder.getAfterSaleStatus(),afterSaleExpiredTime);
    }



    /**
     * 查询售后订单详细信息
     * @param afterId
     * @return
     */
    public AfterSaleOrderDetailVo getAfterSaleOrderDetail(String afterId){
        AfterSaleOrderDetailVo afterSaleOrderDetailVo = new AfterSaleOrderDetailVo();
        AfterSaleOrder afterSaleOrder = shopAfterSaleOrderDao.selectByPrimaryKey(afterId);
        afterSaleOrder.setSpu(JSON.parseObject(afterSaleOrder.getSkuSnapshoot(), OrderSpuVo.class));
        AfterSaleOrderVo afterSaleOrderVo = BeanConverUtils.convertBean(afterSaleOrder, AfterSaleOrderVo.class);
        ParamException.isNull(afterSaleOrderVo);
        afterSaleOrderDetailVo.setAfterSaleOrderVo(afterSaleOrderVo);
        afterSaleOrderDetailVo.setOrderInfoVo(getOrderInfoVo(afterSaleOrderVo.getOrderId()));
        afterSaleOrderDetailVo.setOrderAddrVo(orderAddressServer.getOrderAddr(afterSaleOrderVo.getOrderId()));
        afterSaleOrderDetailVo.setOrderPayVo(orderPayServer.getOrderPay(afterSaleOrderVo.getOrderId()));
        return afterSaleOrderDetailVo;
    }


    public OrderInfoVo getOrderInfoVo(String orderId){
        OrderInfoVo orderInfoVo= BeanConverUtils.convertBean(orderInfoDao.selectByPrimaryKey(orderId), OrderInfoVo.class);
        ParamException.isNull(orderInfoVo);
        return orderInfoVo;
    }


    /**
     * 用户更新售后订单备注
     * @param bo
     * @return
     */

    public void updateRemark(ConfirmAfterSaleBo bo){
        ParamException.isNull(bo.getAfterId(),"售后订单id不能为空");
        shopAfterSaleOrderDao.updateRemark(bo);
    }

    /**
     * 获取售后原因
     * @return
     */
    public Map<String,String> getAfterReason(){
        Map<String,String>map=new HashMap<>();
        for (OrderEnum.AfterReason t :OrderEnum.AfterReason.values()) {
            map.put(t.getCode().toString(),t.getName());
        }
        return map;
    }

    /**
     * 售后退款
     * @return
     */
    @GlobalTransactional(rollbackFor = Exception.class)
    public void refund(String afterId,String userId,String userName,BigDecimal afterSaleAmount){
        ParamException.isBlank(afterId,"售后单号为空");
        AfterSaleOrder afterSaleOrder = shopAfterSaleOrderDao.selectByPrimaryKey(afterId);
        ParamException.isNull(afterSaleOrder);
        if(afterSaleAmount.compareTo(BigDecimal.ZERO)>0){
            afterSaleOrder.setAfterSaleAmount(afterSaleAmount);
            shopAfterSaleOrderDao.updateByPrimaryKeySelective(afterSaleOrder);
        }

/*        //退货&&退款判断
        if(afterSaleOrder.getAfterSaleType()==OrderEnum.AfterType.RETURN.getCode()){
            ParamException.isTrue(afterSaleOrder.getAfterSaleStatus()!=OrderEnum.AfterStatus.RECEIVED.getCode()&&afterSaleOrder.getAfterSaleStatus()!=OrderEnum.AfterStatus.REFUNDFAIL.getCode(),
                    "当前状态"+OrderEnum.AfterStatus.getValueByCode(afterSaleOrder.getAfterSaleStatus())+"不可以进行退款");
            //退款判断
        }else if (afterSaleOrder.getAfterSaleType()==OrderEnum.AfterType.REFUND.getCode()&&afterSaleOrder.getAfterSaleStatus()!=OrderEnum.AfterStatus.REFUNDFAIL.getCode()){
            ParamException.isTrue(afterSaleOrder.getAfterSaleStatus()!=OrderEnum.AfterStatus.APPLY.getCode(),
                    "当前状态"+OrderEnum.AfterStatus.getValueByCode(afterSaleOrder.getAfterSaleStatus())+"不可以进行退款");
        }*/
        //扣除佣金
        walletApi.submitOrderRefund(afterSaleOrder.getOrderId(),afterSaleOrder.getSpuOrderId(),afterSaleOrder.getAfterSaleAmount(),afterSaleOrder.getId(),afterSaleOrder.getSkuQty());
        //调三方支付
        OrderRefundCreBo creBo=new OrderRefundCreBo();
        creBo.setBizRefundsNo(afterSaleOrder.getId());
        creBo.setOperatorId(userId);
        creBo.setOperatorName(userName);
        OrderPay orderPay = orderPayDao.query(afterSaleOrder.getOrderId());
        ParamException.isNull(orderPay,"付款信息为空");
        creBo.setFundsPayId(orderPay.getFundsPayId());
        creBo.setTradeNo(orderPay.getTradeNo());
        creBo.setOrderId(orderPay.getId());
        creBo.setRefundAmount(afterSaleOrder.getAfterSaleAmount());
        creBo.setNotifyMethod(RabbitMqConstants.SHOP_AFTER_SALE_REFUND_QUEUE);
        log.info("fundsApi.create param {}",JSON.toJSONString(creBo));
        OrderRefundsVo result = fundsApi.refundsCre(creBo).getResult();
        log.info("fundsApi.create result {}",JSON.toJSONString(result));
        ParamException.isNull(result,"退款失败");
        if (result.getStatus().equals(OrderEnum.PayStatus.FILL.getCode())){
            walletApi.cancleOrderRefund(afterSaleOrder.getId());
            ParamException.isTrue(true,"退款申请提交失败");
        }
        //退货&&退款
        if(afterSaleOrder.getAfterSaleType().equals(OrderEnum.AfterType.RETURN.getCode())){
            if (result.getStatus().equals(OrderEnum.PayStatus.PRE.getCode())||result.getStatus().equals(OrderEnum.PayStatus.CRE.getCode())) {
                updateStatus(afterSaleOrder.getId(),OrderEnum.AfterStatus.REFUNDING.getCode());
            }
            if (result.getStatus().equals(OrderEnum.PayStatus.SUCCEED.getCode())) {
                updateStatus(afterSaleOrder.getId(),OrderEnum.AfterStatus.REFUNDED.getCode());
                walletApi.finishOrderRefund(afterSaleOrder.getId());
            }
            //updateStatus(afterSaleOrder.getId(),OrderEnum.AfterStatus.REFUNDING.getCode());
            //退款
        }else if (afterSaleOrder.getAfterSaleType().equals(OrderEnum.AfterType.REFUND.getCode())){
            //updateStatus(afterSaleOrder.getId(),OrderEnum.AfterStatus.REFUNDING.getCode());
            if (result.getStatus().equals(OrderEnum.PayStatus.PRE.getCode())||result.getStatus().equals(OrderEnum.PayStatus.CRE.getCode())) {
                updateStatus(afterSaleOrder.getId(),OrderEnum.AfterStatus.REFUNDING.getCode());
            }
            if (result.getStatus().equals(OrderEnum.PayStatus.SUCCEED.getCode())) {
                updateStatus(afterSaleOrder.getId(),OrderEnum.AfterStatus.REFUNDED.getCode());
                walletApi.finishOrderRefund(afterSaleOrder.getId());
            }
        }
        //更新零售订单状态
        OrderInfo orderInfo=new OrderInfo();
        orderInfo.setId(afterSaleOrder.getOrderId());

        OrderSpu orderSpu = new OrderSpu();
        orderSpu.setId(afterSaleOrder.getSpuOrderId());
        if ((result.getStatus().equals(OrderEnum.PayStatus.PRE.getCode())||result.getStatus().equals(OrderEnum.PayStatus.CRE.getCode()))
                && afterSaleOrder.getAfterSaleType().equals(OrderEnum.AfterType.REFUND.getCode())) {
            //orderInfo.setStatus(5);
            orderSpu.setIsAfterSale(5);
            orderSpu.setAfterSaleStatus(5);
        }
        if (result.getStatus().equals(OrderEnum.PayStatus.SUCCEED.getCode())){
            orderInfo.setIsAfterSale(2);
            if (afterSaleOrder.getAfterSaleType().equals(OrderEnum.AfterType.REFUND.getCode())){
                orderSpu.setIsAfterSale(6);
                orderSpu.setAfterSaleStatus(6);
            }else {
                //校验是否已经退款所有
                Boolean bool = checkAllReturn(afterSaleOrder.getSpuOrderId());
                if (bool) {
                    orderSpu.setIsAfterSale(6);
                    orderSpu.setAfterSaleStatus(6);
                }else{
                    orderSpu.setIsAfterSale(2);
                }
            }
            //更新佣金单状态
            walletApi.submitOrderRefund(afterSaleOrder.getOrderId(),afterSaleOrder.getSpuOrderId(),afterSaleOrder.getAfterSaleAmount(),afterSaleOrder.getId(),afterSaleOrder.getSkuQty());
        }
        orderSpuDao.updateByPrimaryKeySelective(orderSpu);

        //更新快照售后信息
        upSkuSnapshoot(afterSaleOrder.getOrderId());

        //全退款零售单更新成已退款
        if (result.getStatus().equals(OrderEnum.PayStatus.SUCCEED.getCode())&&afterSaleOrder.getAfterSaleType()==OrderEnum.AfterType.REFUND.getCode()){
            OrderSpu spu = new OrderSpu();
            spu.setOrderId(afterSaleOrder.getOrderId());
            List<OrderSpu> spuList = orderSpuDao.select(spu);
            List<OrderSpu> list = spuList.stream().filter( o -> o.getIsAfterSale() == null || o.getIsAfterSale() != 6).collect(Collectors.toList());
            if (list == null || list.size() == 0) {
                orderInfo.setStatus(OrderEnum.OrderStatus.REFUND.getCode());
            }
            Integer check = checkOrderDelivery(afterSaleOrder.getOrderId());
            if (check==OrderEnum.OrderStatus.SEND.getCode()){
                orderInfo.setStatus(OrderEnum.OrderStatus.SEND.getCode());
            }
        }
        orderInfoDao.updateByPrimaryKeySelective(orderInfo);
        if (OrderEnum.OrderStatus.REFUND.getCode().equals(orderInfo.getStatus())){
            OrderInfo info = orderInfoDao.selectByPrimaryKey(afterSaleOrder.getOrderId());
            String disOrder=JSON.toJSONString(info);
            //通知分消对订单分消信息进行结算
            rabbitTemplate.convertAndSend(RabbitMqConstants.DIST_ORDER_CALCULATE_QUEUE,disOrder);
        }
    }

    private Boolean checkAllReturn(String spuOrderId) {
        OrderSpu spu = orderSpuDao.selectByPrimaryKey(spuOrderId);
        List<AfterSaleOrder> afterSaleOrders = shopAfterSaleOrderDao.queryOrderSpuAfterSale(spuOrderId);
        if (!CollectionUtils.isEmpty(afterSaleOrders)){
            Integer sum = afterSaleOrders.stream().filter(o -> o.getAfterSaleType().equals(OrderEnum.AfterType.RETURN.getCode())
                    && o.getAfterSaleStatus().equals(OrderEnum.AfterStatus.REFUNDED.getCode())).mapToInt(AfterSaleOrder::getSkuQty).sum();
            if (sum!=null&& spu.getSkuQty().equals(sum)){
                return true;
            }
        }
        return false;
    }

    /**
     * 更新状态
     * @return
     */
    public void updateStatus(String afterId,Integer status){
        ParamException.isBlank(afterId,"售后单号为空");
        AfterSaleOrder afterSaleOrder = shopAfterSaleOrderDao.selectByPrimaryKey(afterId);
        ParamException.isNull(afterSaleOrder);
        AfterSaleOrder afterSaleOrder1=new AfterSaleOrder();
        afterSaleOrder1.setId(afterId);
        afterSaleOrder1.setAfterSaleStatus(status);
        shopAfterSaleOrderDao.updateByPrimaryKeySelective(afterSaleOrder1);
    }





    /**
     * 订单过期关闭
     * @return
     */
    public void orderAutoClosed(){
        List<AfterSaleOrder> afterSaleOrders = shopAfterSaleOrderDao.selectExpirationOrder();
        afterSaleOrders.forEach(AfterSaleOrder -> {
            //关闭订单
            shopAfterSaleOrderDao.afterSaleOrderClosed(AfterSaleOrder.getId());
            OrderSpu orderSpu = new OrderSpu();
            orderSpu.setId(AfterSaleOrder.getSpuOrderId());
            orderSpu.setIsAfterSale(2);
            orderSpu.setAfterSaleStatus(OrderEnum.AfterStatus.END.getCode());
            orderSpuDao.updateByPrimaryKeySelective(orderSpu);

            //更新快照售后信息
            upSkuSnapshoot(AfterSaleOrder.getOrderId());
        });
    }

    /**
     * 退款成功
     */
    @Transactional(rollbackFor = Exception.class)
    public void completeRefund(OrderRefundsVo orderRefundsVo){
        ParamException.isBlank(orderRefundsVo.getBizRefundsNo(),"售后单号为空");
        AfterSaleOrder afterSaleOrder = shopAfterSaleOrderDao.selectByPrimaryKey(orderRefundsVo.getBizRefundsNo());
        ParamException.isNull(afterSaleOrder);
        //只处理支付成功的订单
      //  ParamException.isFalse(OrderEnum.PayStatus.SUCCEED.getCode().equals(orderRefundsVo.getStatus()));
/*        ParamException.isTrue(afterSaleOrder.getAfterSaleStatus()!=OrderEnum.AfterStatus.REFUNDING.getCode(),
                "当前状态"+OrderEnum.AfterStatus.getValueByCode(afterSaleOrder.getAfterSaleStatus())+"不可以完成退款");*/

        //只处理成功或者失败的请求
        if(OrderEnum.PayStatus.SUCCEED.getCode().equals(orderRefundsVo.getStatus())){
            updateStatus(afterSaleOrder.getId(),OrderEnum.AfterStatus.REFUNDED.getCode());
            //更新零售订单状态
            OrderInfo orderInfo=new OrderInfo();
            orderInfo.setId(afterSaleOrder.getOrderId());
            OrderSpu orderSpu = new OrderSpu();
            orderSpu.setId(afterSaleOrder.getSpuOrderId());
            //仅退款
            if (afterSaleOrder.getAfterSaleType().equals(OrderEnum.AfterType.REFUND.getCode())){
                orderSpu.setIsAfterSale(6);
                orderSpu.setAfterSaleStatus(6);
            }else {
                //校验是否已经退款所有
                Boolean bool = checkAllReturn(afterSaleOrder.getSpuOrderId());
                if (bool) {
                    orderSpu.setIsAfterSale(6);
                    orderSpu.setAfterSaleStatus(6);
                }else{
                    orderSpu.setIsAfterSale(2);
                }
            }
            orderSpuDao.updateByPrimaryKeySelective(orderSpu);

            //更新售后状态快照
            upSkuSnapshoot(afterSaleOrder.getOrderId());

            //仅退款
            if (OrderEnum.AfterType.REFUND.getCode().equals(afterSaleOrder.getAfterSaleType())){
                OrderSpu spu = new OrderSpu();
                spu.setOrderId(afterSaleOrder.getOrderId());
                List<OrderSpu> spuList = orderSpuDao.select(spu);
                List<OrderSpu> list = spuList.stream().filter(o -> o.getIsAfterSale() == null || o.getIsAfterSale() != 6).collect(Collectors.toList());
                if (list == null || list.size() == 0) {
                    orderInfo.setStatus(OrderEnum.OrderStatus.REFUND.getCode());
                }
                //校验订单发货状态
                Integer check = checkOrderDelivery(afterSaleOrder.getOrderId());
                if (check==OrderEnum.OrderStatus.SEND.getCode()){
                    orderInfo.setStatus(OrderEnum.OrderStatus.SEND.getCode());
                }
            }
            orderInfo.setIsAfterSale(2);
            orderInfoDao.updateByPrimaryKeySelective(orderInfo);
            //更新佣金单状态
            walletApi.finishOrderRefund(afterSaleOrder.getId());

            //通知分消对订单分消信息进行结算
            if (OrderEnum.OrderStatus.REFUND.getCode().equals(orderInfo.getStatus())){
                OrderInfo info = orderInfoDao.selectByPrimaryKey(afterSaleOrder.getOrderId());
                String disOrder=JSON.toJSONString(info);
                rabbitTemplate.convertAndSend(RabbitMqConstants.DIST_ORDER_CALCULATE_QUEUE,disOrder);
            }
        }
        if(OrderEnum.PayStatus.FILL.getCode().equals(orderRefundsVo.getStatus())){
            OrderInfo orderInfo=new OrderInfo();
            orderInfo.setId(afterSaleOrder.getOrderId());
            OrderSpu orderSpu = new OrderSpu();
            orderSpu.setId(afterSaleOrder.getSpuOrderId());
            orderSpu.setIsAfterSale(1);
            updateStatus(afterSaleOrder.getId(),OrderEnum.AfterStatus.REFUNDFAIL.getCode());
/*            if (OrderEnum.AfterType.REFUND.getCode().equals(afterSaleOrder.getAfterSaleType())){
                updateStatus(afterSaleOrder.getId(),OrderEnum.AfterStatus.APPLY.getCode());
            }else {
                updateStatus(afterSaleOrder.getId(),OrderEnum.AfterStatus.RECEIVED.getCode());
            }*/
            orderSpuDao.updateByPrimaryKeySelective(orderSpu);
            //更新售后状态快照
            upSkuSnapshoot(afterSaleOrder.getOrderId());
            walletApi.cancleOrderRefund(afterSaleOrder.getId());
        }
//        updateStatus(afterSaleOrder.getId(),OrderEnum.AfterStatus.REFUNDED.getCode());
//        //仅退款
///*        if (afterSaleOrder.getAfterSaleType()==OrderEnum.AfterType.REFUND.getCode()){
//        }*/
//        //更新零售订单状态
//        OrderInfo orderInfo=new OrderInfo();
//        orderInfo.setId(afterSaleOrder.getOrderId());
//        orderInfo.setStatus(6);
//        orderInfo.setIsAfterSale(2);
//        orderInfoDao.updateByPrimaryKeySelective(orderInfo);

    }

    /**
     * 检查退款状态
     * 是否可以售后检查:
     * 3.已经退了所有数量所以不能售后 4.已过期不能售后 5可以售后 6订单未支付,不能退款
     */
    public AfterSaleOrderCheckVo checkAfterSale(String spuOrderId){
        AfterSaleOrderCheckVo afterSaleOrderCheckVo=new AfterSaleOrderCheckVo();
        afterSaleOrderCheckVo.setSpuOrderId(spuOrderId);
        afterSaleOrderCheckVo.setAfterSaleCheck(5);

        OrderSpu spu = orderSpuDao.selectByPrimaryKey(spuOrderId);
        ParamException.isTrue(spu==null,"订单["+spuOrderId+"]不存在");

        afterSaleOrderCheckVo.setAllowAfterAmounts(spu.getRealPrice().multiply(new BigDecimal(spu.getSkuQty())));
        afterSaleOrderCheckVo.setAllowAfterQty(spu.getSkuQty());

        //判断是否已经过售后保质期
        AfterSaleOrder afterSaleOrder=new AfterSaleOrder();
        afterSaleOrder.setSpuOrderId(spu.getId());
        List<AfterSaleOrder> afterSaleOrderList = shopAfterSaleOrderDao.select(afterSaleOrder);
        OrderInfo orderInfo=new OrderInfo();
        orderInfo.setId(spu.getOrderId());
        OrderInfo orderInfo2 = orderInfoDao.selectOne(orderInfo);
        //校验是否过保修期
        if (orderInfo2.getRepairTime()!=null&&orderInfo2.getRepairTime().compareTo(Instant.now())<0){
            afterSaleOrderCheckVo.setAfterSaleCheck(4);
            return afterSaleOrderCheckVo;
        }

        //校验是否未付款
        if (orderInfo2.getStatus()==0){
            afterSaleOrderCheckVo.setAfterSaleCheck(6);
            return afterSaleOrderCheckVo;
        }

        if (afterSaleOrderList!=null&&afterSaleOrderList.size()!=0){
            //校验是否有在进行的售后
            for (AfterSaleOrder o:afterSaleOrderList) {
                if (o.getAfterSaleStatus()>=1&&o.getAfterSaleStatus()<=5){
                    afterSaleOrderCheckVo.setAfterSaleCheck(1);
                    return afterSaleOrderCheckVo;
                }
            }

            //已退款数量
            int qty = afterSaleOrderList.stream().filter(o -> o.getAfterSaleStatus() == 6 && o.getSkuQty() != null)
                    .mapToInt(AfterSaleOrder::getSkuQty).sum();

            //校验已经退了所有数量
            if (qty>=spu.getSkuQty()){
                afterSaleOrderCheckVo.setAfterSaleCheck(3);
                return afterSaleOrderCheckVo;
            }
            afterSaleOrderCheckVo.setAllowAfterQty(spu.getSkuQty()-qty);
        }

        return afterSaleOrderCheckVo;
    }



    /**
     * 检测订单发货状态,如果2件商品按商品发货,如果1件商品已经发货,另1件进行了退款,订单更新成已发货
     * @param orderId
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer  checkOrderDelivery(String orderId){
        ParamException.isBlank(orderId,"订单id为空");
        OrderListApiBo orderListApiBo=new OrderListApiBo();
        orderListApiBo.setOrderId(orderId);
        List<OrderAddr> orderAddr = orderAddrDao.queryOrderAddrs(orderListApiBo);
        ParamException.isTrue(orderAddr==null||orderAddr.size()==0,"订单不存在或者未付款");

        OrderSpu spu=new OrderSpu();
        spu.setOrderId(orderId);
        //未售后单据
        //List<OrderSpu> orderSpus = orderSpuDao.select(spu).stream().filter(o->o.getIsAfterSale()==null||o.getIsAfterSale()==0).collect(Collectors.toList());
        //已售后单据
        List<OrderSpu> orderSpus2 = orderSpuDao.select(spu).stream().filter(o->o.getIsAfterSale()!=null&&o.getIsAfterSale()!=0).collect(Collectors.toList());

        //查询未发货订单
        List<OrderAddr> list = orderAddr.stream()
                .filter(o->o.getType()== OrderEnum.AddrOrderStatus.UN_SEND.getCode()).collect(Collectors.toList());

        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setId(orderAddr.get(0).getOrderId());
        orderInfo.setStatus(OrderEnum.OrderStatus.SEND.getCode());

        if (list!=null&&list.size()!=0){
            Integer num=0;
            for (OrderAddr addr:list) {
                for (OrderSpu orderSpu:orderSpus2) {
                    if (orderSpu.getSkuId().equals(addr.getSkuId())){
                        num=num+1;
                    }
                }
            }
            if (num==list.size()&&list.size()!=orderAddr.size()){
                return  OrderEnum.OrderStatus.SEND.getCode();
            }
        }

        return OrderEnum.OrderStatus.PAYED.getCode();
    }

    public void afterSaleAutoRefund() {
        List<Integer> list=new ArrayList<>();
        list.add(OrderEnum.AfterStatus.APPLY.getCode());
        List<Integer> types=new ArrayList<>();
        types.add(OrderEnum.AfterType.REFUND.getCode());
        List<AfterSaleOrder> afterSaleOrders = shopAfterSaleOrderDao.selectAutoRefundOrder(list,types);
        afterSaleOrders.forEach(afterSaleOrder -> {
            refund(afterSaleOrder.getId(),"","",BigDecimal.ZERO);
        });
    }
}
